package com.asm.netty.f_bytebuf;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import org.junit.Test;

import static io.netty.buffer.ByteBufUtil.appendPrettyHexDump;
import static io.netty.util.internal.StringUtil.NEWLINE;

/*
Unpooled 是一个工具类，类如其名，提供了非池化的 ByteBuf 创建、组合、复制等操作
Unpooled.wrappedBuffer 方法

 */
public class e_Unpooled {

    /**
     * 零拷贝 与 池化非池化 buf无关
     */
    @Test
    public void test0()
    {
        final ByteBuf buf1 = Unpooled.buffer(5);
        buf1.writeBytes(new byte[]{1,2,3,4,5});
        final ByteBuf buf2 = ByteBufAllocator.DEFAULT.buffer(5);
        buf2.writeBytes(new byte[]{6,7,8,9,10});

        System.out.println(buf1.getClass()); // : class io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf   非池化堆内存
        System.out.println(buf2.getClass()); // : class io.netty.buffer.PooledUnsafeDirectByteBuf     池化直接内存
        // 非池化堆内存 进行零拷贝
        final ByteBuf s = buf1.slice(0, 2);
        System.out.println(s.getClass()); //  class io.netty.buffer.UnpooledSlicedByteBuf
        log(s);
        /*
        read index:0 write index:2 capacity:2
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 01 02                                           |..              |
+--------+-------------------------------------------------+----------------+
         */
        buf1.setByte(0,15);
        log(s);
        /*
        read index:0 write index:2 capacity:2
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 0f 02                                           |..              |
+--------+-------------------------------------------------+----------------+
         */

    }

    public static void main(String[] args) {

        final ByteBuf buf1 = Unpooled.buffer(5);
        buf1.writeBytes(new byte[]{1,2,3,4,5});
        final ByteBuf buf2 = ByteBufAllocator.DEFAULT.buffer(5);
        buf2.writeBytes(new byte[]{6,7,8,9,10});

        System.out.println(buf1.getClass()); // : class io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf   非池化堆内存
        System.out.println(buf2.getClass()); // : class io.netty.buffer.PooledUnsafeDirectByteBuf     池化直接内存

        // wrappedBuffer 包装超过一个时，底层使用 CompositeByteBuf
        final ByteBuf bufAll = Unpooled.wrappedBuffer(buf1, buf2);
        log(bufAll);
        /*
        read index:0 write index:10 capacity:10
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 01 02 03 04 05 06 07 08 09 0a                   |..........      |
+--------+-------------------------------------------------+----------------+
         */
        buf1.setByte(0,16); // 改变 buf1 发现 引用地址的 bufAll 数据改了
        log(bufAll);
        /*
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 10 02 03 04 05 06 07 08 09 0a                   |..........      |
+--------+-------------------------------------------------+----------------+
         */



    }

    private static void log(ByteBuf buffer) {
        int length = buffer.readableBytes();
        int rows = length / 16 + (length % 15 == 0 ? 0 : 1) + 4;
        StringBuilder buf = new StringBuilder(rows * 80 * 2)
                .append("read index:").append(buffer.readerIndex())
                .append(" write index:").append(buffer.writerIndex())
                .append(" capacity:").append(buffer.capacity())
                .append(NEWLINE); // Import static constant... netty的
        appendPrettyHexDump(buf, buffer);
        System.out.println(buf.toString());
    }

}
